/*
Package db :
Copyright Huawei Corp. All Rights Reserved.
*/
package db

import (
	"fmt"
	"github.com/astaxie/beego/orm"
	_ "github.com/go-sql-driver/mysql" //for mysql driver
	"nft-server/config"
	"nft-server/logger"
	"nft-server/util"
)

const (
	GaussSQLDriver  = "gauss"
	DBsqlDriverName = "mysql"
	DBDefaultAlias  = "default"
	DefaultRowsLimit = -1
	ETCDMode         = "etcd" // 容灾模式
)

type GuassDB struct {
}

func (g *GuassDB) Init(c *config.DBConfig) error {
	logger.Info("Start to initialize gauss database.")
	var dbHost string

	if c == nil {
		return fmt.Errorf("DB config is nil")
	}
	if c.DBUser == "" || c.DBName == "" || c.DBPassword == "" {
		return fmt.Errorf("DB user/name/password is nil")
	}

	dbHost, err := g.getDBHost(c)
	if err != nil {
		return err
	}
	if err := orm.RegisterDriver(DBsqlDriverName, orm.DRMySQL); err != nil {
		logger.Error("register driver error: %v", err)
		return err
	}

	logger.Info("start to register database")
	// 不使用GaussDB,datasource不同
	dataSource := g.getDBConfig(dbHost, DBsqlDriverName, c)
	if err = orm.RegisterDataBase(DBDefaultAlias, DBsqlDriverName, dataSource); err != nil {
		logger.Error("register database error: %v", err)
		return fmt.Errorf("register database error: %v", err)
	}

	logger.Info("register database succeed")

	if err := orm.RunSyncdb(DBDefaultAlias, false, true); err != nil {
		logger.Error("run sync database error: %v", err)
		return err
	}

	logger.Info("gauss database initialized.")

	return nil
}

// 拼接IP：port
func (g *GuassDB) getDBHost(c *config.DBConfig) (string, error) {
	var dbHost string
	if c.DBRunMode == ETCDMode {
		if c.DBPort == "" || c.ServiceKey == "" {
			return "", fmt.Errorf("DB servicekey/port is nil")
		}
		dbHost = c.ServiceKey
	} else {
		if c.DBPort == "" || c.DBIP == "" {
			return "", fmt.Errorf("DB ip/port is nil")
		}
		dbHost = c.DBIP
	}
	return dbHost, nil
}

func (g *GuassDB) getDBConfig(dbHost string, driverName string, c *config.DBConfig) string {
	var dbPwdStr string

	dbPwdByte, err := util.DecryptByDefaultAESKey(c.DBPassword)
	if err != nil {
		logger.Error("failed to decrypt db password")
	}
	dbPwdStr = string(dbPwdByte)
	url := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?charset=utf8&loc=Local",
		c.DBUser, dbPwdStr, dbHost, c.DBPort, c.DBName)
	return url
}
